/**
 * @Author: 490912587@qq.com
 * @Description:
 * @File:  Menu
 * @Version: 1.0.0
 * @Date: 2021/11/10 14:39
 */
package model

import (
	"server/tool"
)

type Menu struct {
	BaseModel
	ParentID     int64  `gorm:"comment:'菜单父级ID';default:0"`
	Type         int    `gorm:"comment:'菜单类型（0目录 1菜单 2按钮）';default:0"`
	MenuName     string `gorm:"comment:'菜单名称'"`
	RoutePath    string `gorm:"comment:'前端路由'"`
	Permission   string `gorm:"comment:'前端权限标识'"`
	AssemblyPath string `gorm:"comment:'前端组件路径'"`
	Icon         string `gorm:"comment:'菜单图标'"`
	Sort         int    `gorm:"comment:'排序';default:0"`
}

var menu Menu
var menus []Menu

func (e *Menu) GetList(param tool.Pagination) ([]Menu, error) {
	if err := GlobalDB.Limit(param.PageSize).Offset((param.PageNo - 1) * param.PageSize).Find(&menus).Error; err != nil {
		return menus, err
	}
	return menus, nil
}
func (e *Menu) GetOne(id uint) (Menu, error) {
	if err := GlobalDB.Where("id = ?", id).First(&menu).Error; err != nil {
		return menu, err
	}
	return menu, nil
}
func (e *Menu) Add(model Menu) error {
	if err := GlobalDB.Create(&model).Error; err != nil {
		return err
	}
	return nil
}
func (e *Menu) Edit(model Menu) error {
	if err := GlobalDB.Updates(&model).Error; err != nil {
		return err
	}
	return nil
}
func (e *Menu) Del(id uint) error {
	if err := GlobalDB.Delete(id).Error; err != nil {
		return err
	}
	return nil
}
func (e *Menu) AddAll(model []Menu) error {
	if err := GlobalDB.Create(&model).Error; err != nil {
		return err
	}
	return nil
}

type MenuTree struct {
	ID           uint
	ParentID     int64      `gorm:"comment:'菜单父级ID'"`
	Type         int        `gorm:"comment:'菜单类型（0目录 1菜单 2按钮）'"`
	MenuName     string     `gorm:"comment:'菜单名称'"`
	RoutePath    string     `gorm:"comment:'前端路由'"`
	Permission   string     `gorm:"comment:'前端权限标识'"`
	AssemblyPath string     `gorm:"comment:'前端组件路径'"`
	Icon         string     `gorm:"comment:'菜单图标'"`
	Status       int        `gorm:"default:0;comment:'状态'"`
	IsDelete     int        `gorm:"default:0;comment:'是否假删除'"`
	CreatedAt    int64      `gorm:"default:0;comment:'创建时间'"`
	UpdatedAt    int64      `gorm:"default:0;comment:'更新时间'"`
	Children     []MenuTree `json:"children"`
}

func (e *Menu) GetMenuTree(parentID int64) []MenuTree {
	var treeList []MenuTree
	var menu []Menu
	var node MenuTree
	err := GlobalDB.Where("parent_id = ?", parentID).Order("sort desc").Find(&menu).Error
	if err == nil {
		for _, v := range menu {
			children := e.GetMenuTree(int64(v.ID))
			node = MenuTree{
				ID:           v.ID,
				ParentID:     v.ParentID,
				Type:         v.Type,
				MenuName:     v.MenuName,
				RoutePath:    v.RoutePath,
				Permission:   v.Permission,
				AssemblyPath: v.AssemblyPath,
				Icon:         v.Icon,
				Status:       v.Status,
				IsDelete:     v.IsDelete,
				CreatedAt:    v.CreatedAt,
				UpdatedAt:    v.UpdatedAt,
			}
			node.Children = children
			treeList = append(treeList, node)
		}
	}
	return treeList
}

// 生成前端路由菜单
type MenuMeta struct {
	Title       string   `json:"title"`
	IsKeepAlive bool     `json:"isKeepAlive"`
	IsAffix     bool     `json:"isAffix"`
	Auth        []string `json:"auth"`
	Icon        string   `json:"icon"`
}
type RouteMenuTree struct {
	Path      string               `json:"path"`
	Name      string               `json:"name"`
	Component string               `json:"component"`
	Redirect  string               `json:"redirect"`
	Meta      MenuMeta             `json:"meta"`
	Children  []RouteMenuChildTree `json:"children"`
}
type RouteMenuChildTree struct {
	Path      string   `json:"path"`
	Name      string   `json:"name"`
	Component string   `json:"component"`
	Meta      MenuMeta `json:"meta"`
}

func (e *Menu) GetRouteMenuTree() []RouteMenuTree {
	var routes []RouteMenuTree
	menus := e.GetMenuTree(0)
	for _, tree := range menus {
		var route RouteMenuTree
		route.Path = tree.RoutePath
		route.Name = tree.RoutePath
		route.Component = tree.RoutePath
		if tree.RoutePath == "/home" {
			route.Redirect = ""
		} else {
			route.Redirect = tree.RoutePath
		}
		if tree.RoutePath == "/home" {
			route.Meta.IsAffix = true
		} else {
			route.Meta.IsAffix = false
		}
		route.Meta.Title = tree.MenuName
		route.Meta.Icon = tree.Icon
		route.Meta.Auth = e.GetRouteAuth(tree.ID, true)
		route.Meta.IsKeepAlive = true
		children := tree.Children
		var routesChildren []RouteMenuChildTree
		var routeChildren RouteMenuChildTree
		for _, item := range children {
			routeChildren.Path = item.RoutePath
			routeChildren.Name = item.RoutePath
			routeChildren.Component = item.AssemblyPath
			routeChildren.Meta.Title = item.MenuName
			routeChildren.Meta.Icon = item.Icon
			routeChildren.Meta.Auth = e.GetRouteAuth(item.ID, false)
			route.Meta.IsKeepAlive = true
			routesChildren = append(routesChildren, routeChildren)
		}
		route.Children = routesChildren
		routes = append(routes, route)
	}
	return routes
}
func (e *Menu) GetRouteAuth(ID uint, isTop bool) []string {
	var menus []Menu
	var menu Menu
	var permissions []string
	errs := GlobalDB.Select("permission").Where("parent_id=?", ID).Find(&menus).Error
	err := GlobalDB.Select("permission").Where("id=?", ID).First(&menu).Error
	if isTop {
		if err == nil {
			return []string{menu.Permission}
		}
		return []string{""}
	} else {
		if errs == nil {
			for _, v := range menus {
				permissions = append(permissions, v.Permission)
			}
			permissions = append(permissions, menu.Permission)
			return permissions
		} else {
			return []string{""}
		}
	}
}
